package com.cs.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.cs.domain.CSCategory;
import com.cs.domain.CSFramePlan;
import com.cs.domain.CSLineItems;
import com.cs.domain.CSPubAttachments;
import com.cs.domain.vo.CSSupplierVO;
import com.cs.domain.vo.File;
import com.cs.domain.vo.FrameLineVO;
import com.cs.domain.vo.FrameworkPlanVO;
import com.cs.mapper.CSFramePlanMapper;
import com.cs.mapper.CSProcurementPlanMapper;
import com.cs.service.CSCodeRulesService;
import com.cs.service.CSFramePlanService;
import com.cs.util.CSRuleCode;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.system.api.model.LoginUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

import static com.cs.util.CSRuleCreate.createCode;

/**
 * @Author：bbdf
 * @Package：com.cs.service.impl
 * @Project：RuoYi-Cloud
 * @name：CSFramePlanServiceImpl
 * @Date：2024-11-19 16:51
 * @Filename：CSFramePlanServiceImpl(框架采购)
 */
@Service
public class CSFramePlanServiceImpl implements CSFramePlanService {
    @Autowired
    private CSFramePlanMapper mapper;
    @Autowired
    private CSProcurementPlanMapper planMapper;
    @Autowired
    private CSCodeRulesService service;


    @Override
    public List<CSFramePlan> getFrameworkPlan(CSFramePlan plan) {
        return mapper.getFrameworkPlan(plan);
    }

    @Override
    public Map getFrameworkPlanDetails(String planCode) {
        List<CSPubAttachments> pubAttachementsListByPlanCode = mapper.getPubAttachementsListByPlanCode(planCode);
        CSFramePlan frameworkPlanDetails = mapper.getFrameworkPlanDetails(planCode);
        List<CSSupplierVO> supplierVOS = mapper.getSupplier(frameworkPlanDetails.gethId(), frameworkPlanDetails.getPlanCode());
        Map<String, Object> map = new HashMap<>();
        map.put("csFramePlan", frameworkPlanDetails);
        map.put("file", pubAttachementsListByPlanCode);
        map.put("supplier", supplierVOS);
        return map;
    }

    @Override
    @Transactional
    public Integer addFrameworkPlan(FrameLineVO frameLineVO) {
        String code = createCode(service, CSRuleCode.FRAMEWORK).getCode();
        FrameworkPlanVO framePlan = frameLineVO.getFramePlan();
        CSFramePlan csFramePlan = new CSFramePlan();
        // 使用 BeanUtil 复制属性，忽略 fileList 属性
        BeanUtil.copyProperties(framePlan, csFramePlan, "fileList");

        LoginUser loginUser = SecurityUtils.getLoginUser();

        List<CSLineItems> csLineItems = frameLineVO.getLineItems().stream().map(item -> {
            System.out.println("item = " + item);
            item.setPlanCode(code);
            item.setvCode(createCode(service, CSRuleCode.LINEPROJECT).getCode());
            return item;
        }).toList();
        Integer integer = planMapper.addLineItems(csLineItems);

        //异步添加附件(有错误可能不会报错)
        CompletableFuture.runAsync(() -> {
            List<CSPubAttachments> csPubAttachments1 = frameLineVO.getFramePlan().getFileList().stream().map(file -> {
                CSPubAttachments csPubAttachments = new CSPubAttachments();
                csPubAttachments.setPlanCode(code);
                csPubAttachments.setAnSize(file.getSize());
                csPubAttachments.setAnName(file.getName());
                csPubAttachments.setAnUrl(file.getUrl());
                return csPubAttachments;
            }).toList();
            planMapper.addPubFile(csPubAttachments1);
        });

        if (integer > 0) {
            csFramePlan.setDeptId(Integer.valueOf(loginUser.getSysUser().getDeptId() + ""));
            csFramePlan.setPlanCode(code);
            System.out.println(loginUser.getUsername() + "水电费是非得失");
            csFramePlan.setPlanFounder(loginUser.getUsername());
            csFramePlan.setPlanStatus(1);
            return mapper.addFrameworkPlan(csFramePlan);
        }
        return null;
    }

    @Override
    public Map<String, Object> getFramePlanByPlanCode(String planCode) {
        List<FrameLineVO> frameLineVO = mapper.getFramePlanByPlanCode(planCode);
        List<CSPubAttachments> csPubAttachments = mapper.getPubAttachementsListByPlanCode(planCode);
        List<File> files = csPubAttachments.stream().map(s -> {
            File file = new File();
            file.setName(s.getAnName());
            file.setSize(s.getAnSize());
            file.setUrl(s.getAnUrl());
            return file;
        }).toList();

        List<FrameLineVO> frameLineVOS = frameLineVO.stream().map(s -> {
            s.getFramePlan().setFileList(files);
            return s;
        }).toList();

        List<CSLineItems> flattenedList = frameLineVOS.stream()
                .flatMap(s -> s.getLineItems().stream())
                .collect(Collectors.toList());

        Map<String, Object> map = new HashMap<>();
        map.put("framePlan", frameLineVOS.get(0).getFramePlan());
        map.put("lineItems", flattenedList);
        return map;
    }


    @Override
    @Transactional
    public R<Integer> editFramePlan(FrameLineVO frameLineVO) {
        List<String> collect = frameLineVO.getLineItems().stream().map(CSLineItems::getvCode).toList();
        Integer integer = planMapper.deleteLineItems(collect);

        String planCode = frameLineVO.getFramePlan().getPlanCode();
        List<CSLineItems> csLineItems = frameLineVO.getLineItems().stream().map(s -> {
            s.setPlanCode(planCode);
            return s;
        }).toList();
        planMapper.addLineItems(csLineItems);

        Integer res = mapper.updateFramePlan(frameLineVO.getFramePlan());
        if (res > 0) {
            if (frameLineVO.getFramePlan().getFileList() != null && frameLineVO.getFramePlan().getFileList().size() > 0) {
                CompletableFuture.runAsync(() -> {
                    planMapper.deleteFileByPlanCode(frameLineVO.getFramePlan().getPlanCode());
                    List<CSPubAttachments> csPubAttachments1 = frameLineVO.getFramePlan().getFileList().stream().map(s -> {
                        CSPubAttachments csPubAttachments = new CSPubAttachments();
                        csPubAttachments.setPlanCode(frameLineVO.getFramePlan().getPlanCode());
                        csPubAttachments.setAnSize(s.getSize());
                        csPubAttachments.setAnName(s.getName());
                        csPubAttachments.setAnUrl(s.getUrl());
                        return csPubAttachments;
                    }).toList();
                    planMapper.addPubFile(csPubAttachments1);
                });
            }
            return R.ok(res, "修改成功");
        }
        return R.fail("修改失败");
    }


    @Override
    public R<List<CSCategory>> getCSType() {
        return R.ok(mapper.getCSType(), "success");
    }

    @Override
    public R<Integer> updateStatusByCode(String planCode) {
        CSFramePlan plan = new CSFramePlan();
        plan.setPlanStatus(2);
        plan.setPlanCode(planCode);
        LoginUser loginUser = SecurityUtils.getLoginUser();
        plan.setPlanPerson(loginUser.getUsername());
        Integer integer = mapper.updateStatusByCode(plan);
        if (integer > 0) {
            return R.ok(1, "成功");
        } else {
            return R.fail(0, "失败");
        }
    }


    @Override
    public R<Integer> allowFrameworkPlan(String planCode) {
        CSFramePlan plan = new CSFramePlan();
        plan.setPlanStatus(3);
        plan.setPlanCode(planCode);
        LoginUser loginUser = SecurityUtils.getLoginUser();
        plan.setPlanPerson(loginUser.getUsername());
        Integer integer = mapper.updateStatusByCode(plan);
        if (integer > 0) {
            return R.ok(1, "成功");
        } else {
            return R.fail(0, "失败");
        }
    }

    @Override
    public R<List<CSSupplierVO>> getSupplierList() {
        List<CSSupplierVO> supplier = mapper.getSupplier(null, null);
        return R.ok(supplier);
    }

    @Override
    public R<Integer> rejectFrameworkPlan(String plaCode) {
        Integer res = mapper.rejectFrameworkPlan(plaCode);
        if (res > 0) {
            return R.ok(1, "success");
        }
        return R.fail(null, "fail");
    }

    @Override
    public R<Integer> deleteFrameworkPlan(String planCode) {
        Integer res = mapper.deleteFrameworkPlan(planCode);
        if (res > 0) {
            return R.ok(1, "success");
        }
        return R.fail(null, "fail");
    }

    @Override
    public int selectFramePlanCount() {
        return mapper.selectFramePlanCount();
    }
}
